package com.syh.jn.scm.service.impl.downstream.purchase;

import cn.redscarf.commons.util.other.ExtAssert;
import cn.redscarf.commons.wrapper.Restrictions;
import cn.redscarf.commons.wrapper.Wrapper;
import com.alibaba.dubbo.config.annotation.Service;
import com.syh.core.ddd.event.annotation.DomainEventHandle;
import com.syh.core.ddd.infrastructure.repository.AggregateRepository;
import com.syh.core.ddd.service.AbstractServiceImpl;
import com.syh.jn.scm.domain.downstream.entity.finance.DownStatementAccountBill;
import com.syh.jn.scm.domain.downstream.entity.logistics.DownLogisticsBill;
import com.syh.jn.scm.domain.downstream.entity.purchase.DownPurchaseReturnOrder;
import com.syh.jn.scm.domain.downstream.event.DownLogisticsBillEvent;
import com.syh.jn.scm.domain.downstream.event.DownPurchaseReturnOrderEvent;
import com.syh.jn.scm.domain.downstream.event.DownStatementAccountBillEvent;
import com.syh.jn.scm.domain.downstream.repository.logistics.DownLogisticsBillRepository;
import com.syh.jn.scm.domain.downstream.repository.purchase.DownPurchaseReturnOrderRepository;
import com.syh.jn.scm.domain.driver.entity.logistics.DriverLogisticsBill;
import com.syh.jn.scm.domain.driver.event.DriverLogisticsBillEvent;
import com.syh.jn.scm.dto.downstream.purchase.DownPurchaseReturnOrderItemVo;
import com.syh.jn.scm.dto.downstream.purchase.DownPurchaseReturnOrderMto;
import com.syh.jn.scm.dto.downstream.purchase.DownPurchaseReturnOrderSto;
import com.syh.jn.scm.dto.downstream.purchase.DownPurchaseReturnOrderVo;
import com.syh.jn.scm.dto.support.FilesDto;
import com.syh.jn.scm.service.api.downstream.finance.enums.DownStatementAccountBillEnum;
import com.syh.jn.scm.service.api.downstream.logistics.enums.DownLogisticsBillEnums;
import com.syh.jn.scm.service.api.downstream.purchase.DownPurchaseReturnOrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * Date:2018/7/9
 * Author:Clown
 * 下游采购退货订单相关业务;
 */
@Service
@Transactional
public class DownPurchaseReturnOrderServiceImpl extends AbstractServiceImpl<DownPurchaseReturnOrderSto,DownPurchaseReturnOrderMto,DownPurchaseReturnOrderVo,DownPurchaseReturnOrder,Long> implements DownPurchaseReturnOrderService {
  @Autowired
  private DownPurchaseReturnOrderRepository downstreamPurchaseReturnOrderRepository;
  @Autowired
  private DownLogisticsBillRepository downLogisticsBillRepository;

  @Override
  protected AggregateRepository<DownPurchaseReturnOrder, Long> getAggregateRepository() {
    return downstreamPurchaseReturnOrderRepository;
  }

  /**
   * 新增下游采购退货单
   *
   * @param sto 下游采购退货单STO
   * @return
   */
  @Override
  public Long save(DownPurchaseReturnOrderSto sto){
    DownPurchaseReturnOrder order = DownPurchaseReturnOrder.createdByDownStream(sto);
    Long id = downstreamPurchaseReturnOrderRepository.add(order);
    this.publicEvent(DownPurchaseReturnOrderEvent.buildDownPurchaseReturnOrderCreated(new Object[]{order}));
    return id;
  }

  /**
   * 修改下游采购退货单
   *
   * @param mto 下游采购退货单MTO
   */
  @Override
  public void update(DownPurchaseReturnOrderMto mto){
    DownPurchaseReturnOrder order = judgeNull(mto.getId());
    DownPurchaseReturnOrder oldOrder = downstreamPurchaseReturnOrderRepository.getById(mto.getId());
    order.modify(mto,order);
    downstreamPurchaseReturnOrderRepository.update(order);
    this.publicEvent(DownPurchaseReturnOrderEvent.buildDownPurchaseReturnOrderUpdated(new Object[]{order,oldOrder}));
  }

  /**
   * 删除下游采购退货单
   *
   * @param id 要删除的下游采购退货单的id
   */
  @Override
  public void delete(Long id){
    DownPurchaseReturnOrder order = judgeNull(id);
    //调用采购退货单删除方法
    order.destroy();
    //从repository中删除
    downstreamPurchaseReturnOrderRepository.remove(order);
  }

  /**
   * 取消采购退货单
   *
   * @param id 要取消的采购退货单的id
   */
  public void cancel(Long id){
    ExtAssert.notNull(id,"id为空");
    //根据id去查找对应的订单
    DownPurchaseReturnOrder order = downstreamPurchaseReturnOrderRepository.getById(id);
    order.cancel();
    downstreamPurchaseReturnOrderRepository.updateStatus(order);
    this.publicEvent(DownPurchaseReturnOrderEvent.buildDownPurchaseReturnOrderCancel(new Object[]{order}));
  }

  /**
   * 根据采购退货订单ids查出明细
   *
   * @param ids
   * @return
   */
  @Override
  public List<DownPurchaseReturnOrderItemVo> getItemsByPurchaseReturnOrderIds(Long[] ids) {
    return downstreamPurchaseReturnOrderRepository.getItemsByPurchaseReturnOrderIds(ids);
  }

  /**
   * 判空方法
   * @param id
   * @return
   */
  private DownPurchaseReturnOrder judgeNull(Long id){
    ExtAssert.notNull(id,"id不能为空");
    DownPurchaseReturnOrder entity = downstreamPurchaseReturnOrderRepository.getById(id);
    ExtAssert.notNull(entity,"订单不存在");
    return entity;
  }

  /**
   * 上传单据图片
   * @param dto
   */
  @Override
  public void upload(FilesDto dto){
    DownPurchaseReturnOrder order = judgeNull(dto.getId());
    order.upload(dto);
    downstreamPurchaseReturnOrderRepository.upload(order);
  }

  /**
   * 消费者：监听物流单创建（记录生成物流商品数量）
   * @param bill
   */
  @DomainEventHandle(DownLogisticsBillEvent.DOWN_LOGISTICS_BILL_CREATED)
  protected void handleLogisticsBillCreated(DownLogisticsBill bill) {
    if (DownLogisticsBillEnums.OrderType.RETURN_PURCHASE.getStatus().equals(bill.getOrderType())) {
      DownPurchaseReturnOrder order = downstreamPurchaseReturnOrderRepository.getById(bill.getOrderId());
      order.countGeneratedQuantity(bill,1);
      downstreamPurchaseReturnOrderRepository.updateOrderAndItems(order);
    }
  }

  /**
   * 消费者：监听物流单删除（记录生成物流商品数量）
   * @param bill
   */
  @DomainEventHandle(DownLogisticsBillEvent.DOWN_LOGISTICS_BILL_DELETED)
  protected void handleLogisticsBillDeleted(DownLogisticsBill bill) {
    if (DownLogisticsBillEnums.OrderType.RETURN_PURCHASE.getStatus().equals(bill.getOrderType())) {
      DownPurchaseReturnOrder order = downstreamPurchaseReturnOrderRepository.getById(bill.getOrderId());
      order.countGeneratedQuantity(bill,2);
      downstreamPurchaseReturnOrderRepository.updateOrderAndItems(order);
    }
  }

  /**
   * 消费者：监听物流单发货事件（修改发货数量）
   * @param bill
   */
  @DomainEventHandle(DownLogisticsBillEvent.DOWN_LOGISTICS_BILL_DELIVERY)
  protected void handleDownLogisticsBillDeliver(DownLogisticsBill bill) {
    if (DownLogisticsBillEnums.OrderType.RETURN_PURCHASE.getStatus().equals(bill.getOrderType())) {
      DownPurchaseReturnOrder order = downstreamPurchaseReturnOrderRepository.getById(bill.getOrderId());
      order.delivery(bill);
      downstreamPurchaseReturnOrderRepository.updateOrderAndItems(order);
    }
  }

  /**
   * 消费者：监听物流单取消发货事件（修改发货数量）
   * @param bill
   */
  @DomainEventHandle(DownLogisticsBillEvent.DOWN_LOGISTICS_BILL_CANCELLED)
  protected void handleDownLogisticsBillCancelled(DownLogisticsBill bill) {
    if (DownLogisticsBillEnums.OrderType.RETURN_PURCHASE.getStatus().equals(bill.getOrderType())) {
      DownPurchaseReturnOrder order = downstreamPurchaseReturnOrderRepository.getById(bill.getOrderId());
      order.cancelDelivery(bill);
      downstreamPurchaseReturnOrderRepository.updateOrderAndItems(order);
    }
  }

  /**
   * 消费者：监听司机端物流单发货事件（修改发货数量）
   * @param bill
   */
  @DomainEventHandle(DriverLogisticsBillEvent.DRIVER_LOGISTICS_BILL_DELIVERY)
  protected void handleDriverLogisticsBillDelivery(DriverLogisticsBill bill) {
    this.handleDownLogisticsBillDeliver(downLogisticsBillRepository.getById(bill.getId()));
  }

  /**
   * 消费者：监听对账单（生成对账单状态和对账单号）
   * @param bill
   */
  @DomainEventHandle(DownStatementAccountBillEvent.DOWN_STATEMENT_BILL_ACCOUNT_CREATED)
  protected void handleDownStatementBillAccountCreated(DownStatementAccountBill bill) {
    bill.getDownStatementAccountBillItems().forEach(item -> {
      if (item.getSourceType() == DownStatementAccountBillEnum.SOURCE_PURCHASE_RETURN_ORD.getStatus()) {
        DownPurchaseReturnOrder purchaseReturnOrder = downstreamPurchaseReturnOrderRepository.getById(item.getSourceId());
        purchaseReturnOrder.generating(bill.getId());
        downstreamPurchaseReturnOrderRepository.upload(purchaseReturnOrder);
      }
    });
  }

  /**
   * 消费者：监听对账单（生成对账单状态和对账单号）
   * @param bill
   */
  @DomainEventHandle(DownStatementAccountBillEvent.DOWN_STATEMENT_BILL_ACCOUNT_UPDATA)
  protected void handleDownStatementBillAccountUpdata(DownStatementAccountBill bill) {
    Wrapper wrapper = Wrapper.build();
    wrapper.append(Restrictions.eq("statementId",bill.getId()));
    List<DownPurchaseReturnOrder> downPurchaseReturnOrders = downstreamPurchaseReturnOrderRepository.getList(wrapper);
    downPurchaseReturnOrders.forEach(downPurchaseReturnOrder -> {
      downPurchaseReturnOrder.cancelGenerating();
      downstreamPurchaseReturnOrderRepository.upload(downPurchaseReturnOrder);
    });
    bill.getDownStatementAccountBillItems().forEach(item -> {
      if (item.getSourceType() == DownStatementAccountBillEnum.SOURCE_PURCHASE_RETURN_ORD.getStatus()) {
        DownPurchaseReturnOrder purchaseReturnOrder = downstreamPurchaseReturnOrderRepository.getById(item.getSourceId());
        purchaseReturnOrder.generating(bill.getId());
        downstreamPurchaseReturnOrderRepository.upload(purchaseReturnOrder);
      }
    });
  }

  /**
   * 消费者：监听对账单（删除对账单状态和对账单号）
   * @param bill
   */
  @DomainEventHandle(DownStatementAccountBillEvent.DOWN_STATEMENT_BILL_ACCOUNT_DESTORY)
  protected void handleDownStatementBillAccountDestory(DownStatementAccountBill bill) {
    bill.getDownStatementAccountBillItems().forEach(item -> {
      if (item.getSourceType() == DownStatementAccountBillEnum.SOURCE_PURCHASE_RETURN_ORD.getStatus()) {
        DownPurchaseReturnOrder purchaseReturnOrder = downstreamPurchaseReturnOrderRepository.getById(item.getSourceId());
        purchaseReturnOrder.cancelGenerating();
        downstreamPurchaseReturnOrderRepository.upload(purchaseReturnOrder);
      }
    });
  }
}
